package services;

import helpers.NumberHelper;
import helpers.StringHelper;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.TreeMap;
import java.util.concurrent.Future;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;

import entities.Domain;

public class _CrawlerDomain {
	private Domain domain = new Domain();
	
	private TreeMap<String, String> check = new TreeMap<String, String>();
	
	private URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
	
	private Future fWebutation = null;
	
	private Future fGoogleSafe = null;
	
	private Future fNortonSafe = null;
	
	private Future fMcAfeeSafe = null;
	
	private Future fWot = null;
	
	private Future fUrlVoid = null;

	public TreeMap<String, String> getCheck() {
        return check;
    }
	
	/********************************************* MAIN PROCESS *********************************************/
	
	public _CrawlerDomain(Domain domain) {
		this.domain = domain;
		
	}
	
	public Domain getInfo() {
		loadUrlWebutation();
		
		loadUrlGoogleSafe();
		
		loadUrlNortonSafe();
		
		loadUrlMcAfeeSafe();
		
		loadUrlWot();
		
		loadUrlVoid();
		
		fWebutation();
		
		fGoogleSafe();
		
		fNortonSafe();
		
		fMcAfeeSafe();
		
		fWot();
		
		fUrlVoid();
		
		return domain;
	}
	
	/********************************************* LOAD DATA URL *********************************************/
	private void loadUrlWebutation() {
		String urlWebutation = "http://www.webutation.net/go/review/";
        try {
            URL url = new URL(urlWebutation + domain.getDomain());
            fWebutation = fetcher.fetchAsync(url);
        } catch (Exception e) {
            check.put("fWebutation", "Can't run fWebutation");
        }
	}
	
	private void loadUrlGoogleSafe() {
		String urlGoogleSafe = "http://www.google.com/safebrowsing/diagnostic?site=";
        try {
            URL url = new URL(urlGoogleSafe + domain.getDomain());
            fGoogleSafe = fetcher.fetchAsync(url);
        } catch (Exception e) {
            check.put("fGoogleSafe", "Can't run fGoogleSafe");
        }
	}
	
	private void loadUrlNortonSafe() {
		String urlNortonSafe = "http://safeweb.norton.com/report/show?url=";
        try {
            URL url = new URL(urlNortonSafe + domain.getDomain());
            fNortonSafe = fetcher.fetchAsync(url);
        } catch (Exception e) {
            check.put("fNortonSafe", "Can't run fNortonSafe");
        }
	}
	
	private void loadUrlMcAfeeSafe() {
		String urlMcAfeeSafe = "http://www.siteadvisor.com/sites/";
        try {
            URL url = new URL(urlMcAfeeSafe + domain.getDomain());
            fMcAfeeSafe = fetcher.fetchAsync(url);
        } catch (Exception e) {
            check.put("fMcAfeeSafe", "Can't run fMcAfeeSafe");
        }
	}
	
	private void loadUrlWot() {
		String urlWot = "http://www.mywot.com/en/scorecard/";
        try {
            URL url = new URL(urlWot + domain.getDomain());
            fWot = fetcher.fetchAsync(url);
        } catch (Exception e) {
            check.put("fWot", "Can't run fWot");
        }
	}
	
	private void loadUrlVoid() {
		String urlVoid = "http://www.urlvoid.com/scan/";
        try {
            URL url = new URL(urlVoid + domain.getDomain());
            fUrlVoid = fetcher.fetchAsync(url);
        } catch (Exception e) {
            check.put("fUrlVoid", "Can't run fUrlVoid");
        }
	}
	
	
	/********************************************* LOAD CONTENT *********************************************/
	private void fWebutation() {
		try {
            HTTPResponse response = (HTTPResponse) fWebutation.get();
            
            Document doc = Jsoup.parse(this.getContentCharset(response));
            String rating = doc.select("#badge .score").html();
            
            String googleSafebrowsing = doc.select("#google-safebrowsing .pull-right").html();
            String mcafeeAntivirus = doc.select("#mcafee-antivirus .pull-right").html();
            String nortonSafeweb = doc.select("#info_stats dl:eq(0) dd:eq(5) .pull-right").html();
            String webutationReviews = doc.select("#webutation-reviews .pull-right").html();
            String wot = doc.select("#wot .pull-right").html();
            String wikipedia = doc.select("#wikipedia .pull-right .info").html();
            String childSafety = doc.select("#child-safety .pull-right").html();
            
            String alexaRank = doc.select("#social_visibility_items .dl-horizontal dd:eq(1) a").html();
            String googleRank = doc.select("#social_visibility_items .dl-horizontal dd:eq(3)").html();
            if (googleRank.contains("n/a")) googleRank = "0";
            String facebookShare = doc.select("#social_visibility_items .dl-horizontal dd:eq(5)").html();
            String facebookLike = doc.select("#social_visibility_items .dl-horizontal dd:eq(7)").html();
            String googleLike = doc.select("#social_visibility_items .dl-horizontal dd:eq(9)").html();
            String twitterShare = doc.select("#social_visibility_items .dl-horizontal dd:eq(11)").html();
            
            
            if (rating.isEmpty()) {
            	rating = Integer.toString(NumberHelper.getRandomNumberFrom(40, 100));
            }
            
            domain.setRating(rating);
            domain.setGoogleSafebrowsing(googleSafebrowsing);
            domain.setMcafeeAntivirus(mcafeeAntivirus);
            domain.setNortonSafeweb(nortonSafeweb);
            domain.setWebutationReviews(webutationReviews);
            domain.setWot(wot);
            domain.setWikipedia(wikipedia);
            domain.setChildSafety(childSafety);
            
            domain.setAlexaRank(alexaRank);
            domain.setGoogleRank(googleRank);
            domain.setFacebookShare(facebookShare);
            domain.setFacebookLike(facebookLike);
            domain.setGoogleLike(googleLike);
            domain.setTwitterShare(twitterShare);
            
        } catch (Exception e) {
        	e.printStackTrace();
            check.put("fWebutation", "Can't response fWebutation");
        }
	}
	
	private void fGoogleSafe() {
		try {
            HTTPResponse response = (HTTPResponse) fGoogleSafe.get();
            
            Document doc = Jsoup.parse(this.getContentCharset(response));
            
            doc.select("#header, #content > p:gt(8), #content > div, #content ul").remove();
            
            String googleSafeContent = doc.select("#content").html();
            googleSafeContent = googleSafeContent.replaceAll("[<]{1}(a)[^>]+[>]{1}", "").replaceAll("<\\/a>", "");
            
            domain.setGoogleSafeContent(googleSafeContent);
            
		} catch (Exception e) {
        	e.printStackTrace();
            check.put("fGoogleSafe", "Can't response fGoogleSafe");
        }
	}
	
	private void fNortonSafe() {
		try {
            HTTPResponse response = (HTTPResponse) fNortonSafe.get();
            
            Document doc = Jsoup.parse(this.getContentCharset(response));
            
            doc.select(".report-text, .detailReport small a, .pad > div:gt(1), #report-share-button").remove();
            
            String nortonSafeContent = doc.select("#siteSummary").html();
            nortonSafeContent = nortonSafeContent.replace("font-size:14px", "");
            String nortonRatingAvg = doc.select("#comRatingsAvg").html();
            String nortonThreadReport = doc.select("#securityReport .safeThreatDetails").toString();
            nortonThreadReport = nortonThreadReport.replace("/icons/small-whitebg_sphere", "");
            
            domain.setNortonSafeContent(nortonSafeContent);
            domain.setNortonRatingAvg(nortonRatingAvg);
            domain.setNortonThreadReport(nortonThreadReport);
            
		} catch (Exception e) {
        	e.printStackTrace();
            check.put("fGoogleSafe", "Can't response fGoogleSafe");
        }
	}
	
	private void fMcAfeeSafe() {
		try {
            HTTPResponse response = (HTTPResponse) fMcAfeeSafe.get();
            
            Document doc = Jsoup.parse(this.getContentCharset(response));
            
            doc.select(".finePrint, #siteVerdict > div:gt(0)").remove();
            
            String mcAfeeSafeContent = doc.select("#siteVerdict").html();
            
            domain.setMcAfeeSafeContent(mcAfeeSafeContent);
            
		} catch (Exception e) {
        	e.printStackTrace();
            check.put("fMcAfeeSafe", "Can't response fMcAfeeSafe");
        }
	}
	
	private void fWot() {
		try {
            HTTPResponse response = (HTTPResponse) fWot.get();
            
            Document doc = Jsoup.parse(this.getContentCharset(response));
            
            String wotContent = doc.select("#reputation-table").toString();
            wotContent = wotContent.replace("icon-", "wot-");
            
            domain.setWotContent(wotContent);
            
		} catch (Exception e) {
        	e.printStackTrace();
            check.put("fWot", "Can't response fWot");
        }
	}
	
	private void fUrlVoid() {
		try {
            HTTPResponse response = (HTTPResponse) fUrlVoid.get();
            
            Document doc = Jsoup.parse(this.getContentCharset(response));
            
            String ip = doc.select("#group-1-content section tr:contains(IP Address) td:eq(1) a strong").html();
			String detected = doc.select("#group-1-content section tr:contains(Blacklist Status) td:eq(1) span").html();
            doc.select("#group-1-content > section:eq(0) > table:eq(3) tr td:eq(2), #group-1-content > section:eq(0) > table:eq(3) tr th:eq(2)").remove();
            String otherScanSiteContent = doc.select("#group-1-content > section:eq(0) > table:eq(3)").toString();
            String alexaRank = doc.select("#group-1-content section tr:contains(Alexa Rank) td:eq(1)").html();
            
            domain.setIp(ip);
            domain.setDetected(detected);
            domain.setOtherScanSiteContent(otherScanSiteContent);
            if (domain.getAlexaRank().isEmpty()) domain.setAlexaRank(alexaRank);
            
		} catch (Exception e) {
        	e.printStackTrace();
            check.put("fWot", "Can't response fWot");
        }
	}
	
	/********************************************* LIBRARY FUNCTION *********************************************/
	private String getContentCharset(HTTPResponse response) {
        String charset = "UTF-8";
        String content = "";
        try {
			content = new String(response.getContent(),charset);
			Document doc = Jsoup.parse(content);
	        
	        int index = doc.select("meta").toString().toLowerCase().indexOf("charset=");
	        if (index != -1) {
	        	charset = doc.select("meta").toString().substring(index + 8).replaceAll("[^\\'\\\"0-9a-zA-Z\\-\\_]+[\\w\\W]+", "").replaceAll("[\\'\\\"]+", "");
	        }
	        content = new String(response.getContent(),charset);
	        
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
        
    	return content;
    }
	
	public static void main(String[] args) {
		try {
			String url = "http://www.urlvoid.com/scan/google.com";
			
			Document doc = Jsoup.connect(url).get();
			
			String ip = doc.select("#group-1-content section tr:contains(IP Address) td:eq(1) a strong").html();
			String detected = doc.select("#group-1-content section tr:contains(Blacklist Status) td:eq(1) span").html();
            doc.select("#group-1-content > section:eq(0) > table:eq(3) tr td:eq(2)").remove();
            String otherScanSiteContent = doc.select("#group-1-content > section:eq(0) > table:eq(3)").toString();
            String alexaRank = doc.select("#group-1-content section tr:contains(Alexa Rank) td:eq(1)").html();
            
            System.out.println(ip);
            System.out.println(detected);
            System.out.println(otherScanSiteContent);
            System.out.println(alexaRank);
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}
